using System;
using System.Web;
using System.Collections.Generic;
using System.Text;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebPartPages;
using Microsoft.SharePoint.Utilities;

namespace ProjectCompliance
{
    /// <summary>
    /// This feature receiver performs tasks for the PageInstances feature's Activation
    /// and Deactivation events, to ensure correct provisioning of the page instances.
    /// Informational messages and errors are written to SharePoint ULS logs.
    /// </summary>
    public class PageInstancesFeatureReceiver : SPFeatureReceiver
    {
        // Names of compliance items
        static string sRulesListName = "Compliance Rules";
        static string sResultsListName = "Compliance Results";
        static string sPagesLibraryName = "Workspace";
        static string sRulesPageName = "ComplianceRulesEditor.aspx";
        static string sResultsPageName = "ComplianceAuditing.aspx";
        static string sReportPageName = "ComplianceReport.aspx";
        static string sRulesPageWebPartZoneName = "Footer";
        static string sResultsPageWebPartZoneName = "Footer";
        static string sReportPageWebPartZoneName = "Footer";

        // Trace tags
        static string sExeName = "ProjectCompliance.FeatureReceivers";
        static string sProductName = "Project Compliance";
        static string sCategoryName = "WebParts"; // Scot Hiller's ULS log viewer can filter by this


        /// <summary>
        /// Add the correct ListViewWebParts to compliance page instances 
        /// when Activating the PageInstances feature.
        /// </summary>
        /// <param name="properties"></param>
        public override void FeatureActivated(SPFeatureReceiverProperties properties)
        {
            string FeatureId = "unknown";
            SPWeb web;
            SPList RulesList = null;
            SPList ResultsList = null;
            SPList PagesLibrary;
            ListViewWebPart RulesListView = null;
            ListViewWebPart ResultsListView = null;
            SPLimitedWebPartManager WebPartCollection = null;

            Guid TraceCorrelation = new Guid();
            bool foundRulesPage = false;
            bool foundResultsPage = false;

            TraceProvider.RegisterTraceProvider();
            TraceProvider.WriteTrace(0, TraceProvider.TraceSeverity.InformationEvent, TraceCorrelation, sExeName, sProductName, sCategoryName, "ProjectCompliance feature receiver activating.  Completing web part pages for compliance reporting feature.");

            try
            {
                FeatureId = properties.Feature.DefinitionId.ToString();
                web = (SPWeb)properties.Feature.Parent;

                // Get lists that we need to provide views of

                try
                { RulesList = web.Lists[sRulesListName]; }
                catch (Exception ex)
                { TraceProvider.WriteTrace(0, TraceProvider.TraceSeverity.CriticalEvent, TraceCorrelation, sExeName, sProductName, sCategoryName, "ProjectCompliance feature receiver unable to find list instance '" + sRulesListName + "'. " + ex.Message); }

                try
                { ResultsList = web.Lists[sResultsListName]; }
                catch (Exception ex)
                { TraceProvider.WriteTrace(0, TraceProvider.TraceSeverity.CriticalEvent, TraceCorrelation, sExeName, sProductName, sCategoryName, "ProjectCompliance feature receiver unable to find list instance '" + sResultsListName + "'. " + ex.Message); }

                // Add ListView web parts to web part pages

                PagesLibrary = web.Lists[sPagesLibraryName];
                foreach (SPListItem item in PagesLibrary.Items)
                {
                    if (item.File.Name == sRulesPageName)
                    {
                        // Add ListView for RulesList to RulesPage
                        RulesListView = new ListViewWebPart();
                        RulesListView.ZoneID = sRulesPageWebPartZoneName;
                        RulesListView.ListName = RulesList.ID.ToString("B").ToUpper();
                        RulesListView.ViewGuid = RulesList.DefaultView.ID.ToString("B").ToUpper();
                        RulesListView.AllowClose = false;
                        RulesListView.AllowHide = false;
                        RulesListView.AllowMinimize = false;
                        RulesListView.ChromeType = System.Web.UI.WebControls.WebParts.PartChromeType.TitleAndBorder;
                        WebPartCollection = web.GetLimitedWebPartManager(sPagesLibraryName +"/" +sRulesPageName, System.Web.UI.WebControls.WebParts.PersonalizationScope.Shared);
                        // Remove instructions web part
                        RemoveWebPart(ref WebPartCollection, "CompletionInstructions", TraceCorrelation);
                        // Add list view web part
                        WebPartCollection.AddWebPart(RulesListView, RulesListView.ZoneID, 0);

                        item.Update();
                        WebPartCollection.Dispose();
                        foundRulesPage = true;
                    }
                    if (item.File.Name == sResultsPageName)
                    {
                        // Add ListView for ResultsList to ResultsPage
                        ResultsListView = new ListViewWebPart();
                        ResultsListView.ZoneID = sResultsPageWebPartZoneName;
                        ResultsListView.ListName = ResultsList.ID.ToString("B").ToUpper();
                        ResultsListView.ViewGuid = ResultsList.DefaultView.ID.ToString("B").ToUpper();
                        ResultsListView.AllowClose = false;
                        ResultsListView.AllowHide = false;
                        ResultsListView.AllowMinimize = false;
                        ResultsListView.ChromeType = System.Web.UI.WebControls.WebParts.PartChromeType.TitleAndBorder; 
                        WebPartCollection = web.GetLimitedWebPartManager(sPagesLibraryName + "/" + sResultsPageName, System.Web.UI.WebControls.WebParts.PersonalizationScope.Shared);
                        // Remove instructions web part
                        RemoveWebPart(ref WebPartCollection, "CompletionInstructions", TraceCorrelation);
                        // Add list view web part
                        WebPartCollection.AddWebPart(ResultsListView, ResultsListView.ZoneID, 0);

                        item.Update();
                        WebPartCollection.Dispose();
                        foundResultsPage = true;
                    }
                    if (item.File.Name == sReportPageName)
                    {
                        // This page doesn't need anything on activation (yet).
                    }
                }
                if ((foundRulesPage) | (foundResultsPage))
                    PagesLibrary.Update();

                if (!foundRulesPage)
                {
                    TraceProvider.WriteTrace(0, TraceProvider.TraceSeverity.CriticalEvent, TraceCorrelation, sExeName, sProductName, sCategoryName, "ProjectCompliance feature receiver did not find a page instance for the Rules Editor (" + sRulesPageName + ") when activating feature " + FeatureId + ". ");
                }
                if (!foundResultsPage)
                {
                    TraceProvider.WriteTrace(0, TraceProvider.TraceSeverity.CriticalEvent, TraceCorrelation, sExeName, sProductName, sCategoryName, "ProjectCompliance feature receiver did not find a page instance for the Results Viewer (" + sResultsPageName + ") when activating feature " + FeatureId + ". ");
                }

            }
            catch (Exception ex)
            {
                TraceProvider.WriteTrace(0, TraceProvider.TraceSeverity.CriticalEvent, TraceCorrelation, sExeName, sProductName, sCategoryName, "Exception from ProjectCompliance feature receiver when activating feature " + FeatureId + ".  " + ex.Message);
            }

            TraceProvider.UnregisterTraceProvider();
        }


        private void RemoveWebPart(ref SPLimitedWebPartManager WebPartManager, string WebPartName, Guid TraceCorrelation)
        {
            System.Web.UI.WebControls.WebParts.WebPart RemovableWebPart = null;

            try
            {
                RemovableWebPart = WebPartManager.WebParts[WebPartName];
                if ((WebPartManager != null) & (RemovableWebPart != null))
                {
                    WebPartManager.DeleteWebPart(RemovableWebPart);
                    WebPartManager.SaveChanges(RemovableWebPart);
                }
                TraceProvider.WriteTrace(0, TraceProvider.TraceSeverity.InformationEvent, TraceCorrelation, sExeName, sProductName, sCategoryName, "Removed &quot;" + WebPartName + "&quot; web part when provisioning new compliance auditing web page at " + SPEncode.HtmlEncode(WebPartManager.ServerRelativeUrl));
            }
            catch (Exception ex)
            {
                TraceProvider.WriteTrace(0, TraceProvider.TraceSeverity.WarningEvent, TraceCorrelation, sExeName, sProductName, sCategoryName, "Error attempting to remove &quot;" + WebPartName + "&quot; web part when provisioning new compliance auditing web page.  " + ex.Message);
            }
        }


        /// <summary>
        /// Delete compliance reporting web part page instances 
        /// when Deactivating the PageInstance feature.
        /// </summary>
        /// <param name="properties"></param>
        public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
        {
            string FeatureId = "unknown";
            SPWeb web;
            SPList PagesLibrary;
            SPListItem item;
            Guid TraceCorrelation = new Guid();
            bool found = false;

            TraceProvider.RegisterTraceProvider();
            TraceProvider.WriteTrace(0, TraceProvider.TraceSeverity.InformationEvent, TraceCorrelation, sExeName, sProductName, sCategoryName, "ProjectCompliance feature receiver deactivating.  Deleting web part pages for compliance reporting feature.");

            try
            {
                FeatureId = properties.Feature.DefinitionId.ToString();
                web = (SPWeb)properties.Feature.Parent;

                try
                {
                    PagesLibrary = web.Lists[sPagesLibraryName];
                    for (int i = PagesLibrary.Items.Count - 1; i >= 0; i--)
                    {
                        item = PagesLibrary.Items[i];
                        if ((item.File.Name == sRulesPageName)
                            | (item.File.Name == sResultsPageName)
                            | (item.File.Name == sReportPageName) )
                        {
                            item.Delete();
                            found = true;
                        }
                    }
                    if (found)
                    {
                        PagesLibrary.Update();
                    }
                    else
                    {
                        TraceProvider.WriteTrace(0, TraceProvider.TraceSeverity.WarningEvent, TraceCorrelation, sExeName, sProductName, sCategoryName, "ProjectCompliance feature receiver did not find page instances to delete when deactivating feature " + FeatureId + ". ");
                    }
                }
                catch (Exception ex)
                { TraceProvider.WriteTrace(0, TraceProvider.TraceSeverity.WarningEvent, TraceCorrelation, sExeName, sProductName, sCategoryName, "ProjectCompliance feature receiver encountered exception trying to delete one or more page instances when deactivating feature " + FeatureId + ". " + ex.Message); }

            }
            catch (Exception ex)
            {
                TraceProvider.WriteTrace(0, TraceProvider.TraceSeverity.CriticalEvent, TraceCorrelation, sExeName, sProductName, sCategoryName, "Exception from ProjectCompliance feature receiver when deactivating feature " + FeatureId + ".  " + ex.Message);
            }

            TraceProvider.UnregisterTraceProvider();
        }


        public override void FeatureInstalled(SPFeatureReceiverProperties properties)
        {
            //SPWeb web;
            //web = (SPWeb)properties.Feature.Parent;
        }


        public override void FeatureUninstalling(SPFeatureReceiverProperties properties)
        {
            //SPWeb web;
            //web = (SPWeb)properties.Feature.Parent;
        }
    }
}
